﻿using AnesSystem;
using Common;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using AnesSystem.ViewModels;
using System.Threading;

namespace AnesSystem.Controls
{
    /// <summary>
    /// CustomComboboxCtrl.xaml 的交互逻辑
    /// </summary>
    public partial class CustomComboboxCtrl : BaseDropDownCtrl
    {
        #region Variables

        private List<CommonComboboxItemModel> _displayList = new List<CommonComboboxItemModel>();
        private CustomComboboxCtrlViewModel _vm;

        private bool isFocus = false;
        private bool isMove = false;
        private bool isEdit = true;

        #endregion

        #region Constructor

        public CustomComboboxCtrl()
        {
            InitializeComponent();
            _vm = new CustomComboboxCtrlViewModel();
            this.DataContext = _vm;
            _listView.Tag = false;
            DefaultDropDownStatus = true;

            _txtName.GotFocus += _txt_GotFocus;
            _txtName.LostFocus += _txtName_LostFocus;

            _txtName.TextChanged += _txtName_TextChanged;
            _txtName.MouseMove += _txtName_MouseMove; ;
            _txtName.MouseLeave += _txtName_MouseLeave;
            _listView.MouseMove += _txtName_MouseMove;
            _listView.MouseLeave += _txtName_MouseLeave;
            TextAlignment = TextAlignment.Center;
            this.LostFocus += _txtName_LostFocus;
            this.PreviewKeyDown += CustomComboboxCtrl_PreviewKeyDown;
            this.Loaded += CustomComboboxCtrl_Loaded;
        }


        #endregion

        #region Properties

        /// <summary>
        /// 获取或设置下拉框高度
        /// </summary>
        public double PullDownHeight
        {
            get
            {
                return _popup.Height;
            }
            set
            {
                _popup.Height = value;
            }
        }

        public bool IsFullDisplay
        {
            set
            {
                _vm.IsFullDisplay = value;
            }
            get
            {
                return _vm.IsFullDisplay;
            }
        }

        public bool DefaultDropDownStatus { get; set; }

        public bool IsEdit
        {
            get
            {
                return isEdit;
            }
            set
            {
                isEdit = value;
                _txtName.IsEdit = value;
            }
        }



        public Visibility CheckBoxVisibility
        {
            get { return (Visibility)GetValue(CheckBoxVisibilityProperty); }
            set { SetValue(CheckBoxVisibilityProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CheckBoxVisibility.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CheckBoxVisibilityProperty =
            DependencyProperty.Register("CheckBoxVisibility", typeof(Visibility), typeof(CustomComboboxCtrl), new PropertyMetadata(Visibility.Collapsed));




        //public int SelectedIndex
        //{
        //    get { return (int)GetValue(SelectedIndexProperty); }
        //    set { SetValue(SelectedIndexProperty, value); }
        //}

        //// Using a DependencyProperty as the backing store for SelectedIndex.  This enables animation, styling, binding, etc...
        //public static readonly DependencyProperty SelectedIndexProperty =
        //    DependencyProperty.Register("SelectedIndex", typeof(int), typeof(CustomComboboxCtrl), new PropertyMetadata(SelectedIndexChangedCallBack));

        //private static void SelectedIndexChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        //{
        //    if (e.NewValue != null)
        //    {
        //        CustomComboboxCtrl ctrl = d as CustomComboboxCtrl;
        //        ctrl._vm.SelectedIndex = int.Parse(e.NewValue.ToString());
        //    }
        //}

        public CommonComboboxItemModel SelectedValue
        {
            get { return (CommonComboboxItemModel)GetValue(SelectedValueProperty); }
            set { SetValue(SelectedValueProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelectedValue.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedValueProperty =
            DependencyProperty.Register("SelectedValue", typeof(CommonComboboxItemModel), typeof(CustomComboboxCtrl), new PropertyMetadata(null, SelectedValueChangedCallBack));

        private static void SelectedValueChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                CustomComboboxCtrl ctrl = d as CustomComboboxCtrl;
                ctrl._vm.SelectedItem = e.NewValue as CommonComboboxItemModel;
            }
        }

        public List<CommonComboboxItemModel> ItemsSource
        {
            get { return (List<CommonComboboxItemModel>)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ItemsSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemsSourceProperty =
            DependencyProperty.Register("ItemsSource", typeof(List<CommonComboboxItemModel>), typeof(CustomComboboxCtrl), new PropertyMetadata(null, ItemsSourceChanged));

        private static void ItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                List<CommonComboboxItemModel> list = e.NewValue as List<CommonComboboxItemModel>;
                if (list != null)
                {
                    CustomComboboxCtrl ctrl = d as CustomComboboxCtrl;

                    ctrl._vm.ItemsSource = list;
                }
            }
        }

        #endregion

        #region 依赖属性


        #endregion

        #region Event

        #endregion

        #region Private Methods

        private void FillValue(string value)
        {
            _txtName.TextChanged -= _txtName_TextChanged;

            DataManager.Instance.IsNotNeedSaveData = true;
            Value = "";
            DataManager.Instance.IsNotNeedSaveData = false;
            SetValue(value);
            _txtName.SelectionStart = Value.ToString().Length;
            if (SelectionMode == SelectionMode.Single)
            {
                _popup.IsOpen = false;
                HotKeyManger.Instance.IsDropDownOpen = false;
            }

            _txtName.TextChanged += _txtName_TextChanged;

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="model"></param>
        /// <param name="isSetChecked">是否需要设置checked</param>
        private void SetValueBySelectedItem(CommonComboboxItemModel model, bool isSetChecked = true)
        {
            if (model == null) return;

            if (SelectionMode == SelectionMode.Single)
            {
                FillValue(model.Behind);
            }
            else
            {
                if (isSetChecked)
                {
                    model.IsSelected = !model.IsSelected;
                }
                _vm.CancelOtherChecked(model);
                FillValue(_vm.GetValues());
            }
        }

        #endregion

        #region Public/Protected Methods

        public virtual void SetValue(string value)
        {
            Value = value;
            UpdateLayout();
        }

        #endregion

        #region EventHandlers

        private void _txtName_MouseMove(object sender, MouseEventArgs e)
        {
            isMove = true;
            if (isFocus && !_popup.IsOpen && IsEdit)
            {
                _popup.IsOpen = true;
            }
        }

        private void _txtName_MouseLeave(object sender, MouseEventArgs e)
        {
            try
            {
                isMove = false;
                Task.Factory.StartNew(delegate
                {
                    Thread.Sleep(300);
                    Dispatcher.Invoke(delegate
                    {
                        if (!isMove)
                        {
                            _popup.IsOpen = false;
                            HotKeyManger.Instance.IsDropDownOpen = false;
                            UpdateLayout();
                        }
                    });
                });
            }
            catch (Exception ex)
            {
                LogHelper.Error(this.GetType(), ex);
            }
        }

        private void _txtName_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            _popup.IsOpen = true;
        }


        private void _txtName_LostFocus(object sender, RoutedEventArgs e)
        {
            if (SelectionMode == SelectionMode.Multiple) return;
            _popup.IsOpen = false;
            isFocus = false;
            HotKeyManger.Instance.IsDropDownOpen = false;
        }

        private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            SetValueBySelectedItem((sender as Grid).DataContext as CommonComboboxItemModel);
        }

        private void _txtName_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (DataManager.Instance.IsNotNeedSaveData)
            {
                _popup.IsOpen = false;
                HotKeyManger.Instance.IsDropDownOpen = false;
                return;
            }
            if (isFocus) _popup.IsOpen = true;
            else
            {
                _popup.IsOpen = false;
                HotKeyManger.Instance.IsDropDownOpen = false;
            }
            string txt = (sender as TextBox).Text;
            _vm.Search(txt);
        }

        private void _popup_Opened(object sender, EventArgs e)
        {
            if (_popup.IsOpen)
            {
                HotKeyManger.Instance.IsDropDownOpen = true;
            }
            else
            {
                HotKeyManger.Instance.IsDropDownOpen = false;
            }
        }

        private void _listView_PreviewKeyDown(object sender, KeyEventArgs e)
        {

        }

        private void CustomComboboxCtrl_Loaded(object sender, RoutedEventArgs e)
        {
            if (SelectionMode == SelectionMode.Single)
            {
                CheckBoxVisibility = Visibility.Collapsed;
            }
            else if (SelectionMode == SelectionMode.Multiple)
            {
                CheckBoxVisibility = Visibility.Visible;
                if (Value != null && !string.IsNullOrEmpty(Value.ToString()))
                {
                    string[] values = Value.ToString().Split(';');
                    foreach (var item in ItemsSource)
                    {
                        if (values.Contains(item.Behind))
                        {
                            item.IsSelected = true;
                        }
                    }
                }
            }
        }

        private void CustomComboboxCtrl_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Up || e.Key == Key.Down)
            {
                if (e.Key == Key.Up && _listView.SelectedIndex > 0)
                {
                    _listView.SelectedIndex--;
                }
                else if (e.Key == Key.Down && _listView.SelectedIndex < _listView.Items.Count)
                {
                    _listView.SelectedIndex++;
                }
                e.Handled = true;
            }

            else if (e.Key == Key.Enter)
            {
                SetValueBySelectedItem(_listView.SelectedValue as CommonComboboxItemModel);
                e.Handled = true;
            }

        }

        private void _txt_GotFocus(object sender, RoutedEventArgs e)
        {
            isFocus = true;
            if (DefaultDropDownStatus)
            {
                _popup.IsOpen = true;
                _vm.Search("");
            }
        }
        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            CheckBox ck = sender as CheckBox;
            ck.Checked -= CheckBox_Checked;
            SetValueBySelectedItem(ck.DataContext as CommonComboboxItemModel, false);
            ck.Checked += CheckBox_Checked;
        }

        #endregion


    }
}
